package router

import (
	"context"
	"fmt"
	"ginfast/api"
	"ginfast/api/dashboard"
	"ginfast/api/system"
	"ginfast/configs"
	"ginfast/middleware"
	"ginfast/pkg/log"
	"ginfast/views"
	"net/http"
	"time"

	"github.com/gin-gonic/gin"
)

type Options struct {
	Timeout int64
	Port    uint16
	Root    string
	Public  string
}

// initRouter 创建gin对象
func initRouter(o *Options) *gin.Engine {
	gin.SetMode(gin.ReleaseMode)
	r := gin.Default()
	r.Use(gin.Logger()) // 日志
	// r.Use(middleware.LoadTLS()) // https
	r.Use(middleware.Cors()) // 跨域
	views.Static(r, o.Root)
	v1 := r.Group("/api/v1")
	api.DBInit{}.Router(v1.Group("/dbInit"))
	system.Routers(v1.Group("/system"))
	dashboard.Routers(v1.Group("/dashboard"))
	jwt := middleware.UseJWTAuth(v1.Group(""))
	jwt.POST("/upload/picture", api.UploadPicHandler)
	return r
}

var s *http.Server

// New
func Run() error {
	var opts Options
	if err := configs.GViper.UnmarshalKey("serve", &opts); err != nil {
		return err
	}
	r := initRouter(&opts)
	address := fmt.Sprintf(":%d", opts.Port)
	s := &http.Server{
		Addr:           address,
		Handler:        r,
		ReadTimeout:    time.Duration(opts.Timeout) * time.Second,
		WriteTimeout:   time.Duration(opts.Timeout) * time.Second,
		MaxHeaderBytes: 1 << 20,
	}
	log.ZapLogger.Info("http server start at ", address)
	go s.ListenAndServe()
	return nil
}

func Shutdown() error {
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	s.Shutdown(ctx)
	// catching gctx.Done(). timeout of 5 seconds.
	<-ctx.Done()
	return nil
}
